#include <adwin/ADwinSystem.h>
#include <adwin/ADwinSystemException.h>
#include <adwin/Parameter.h>
#include <adwin/Tools.h>
#include <src/ADwin_V2.h>

namespace ADwin {
namespace Driver {
struct Parameter::Impl {
  Impl(ADwinSystem* adwinSystem, int parameterNumber)
      : _adwinSystem(adwinSystem), _parameterNumber(parameterNumber) {}

  int value() const {
    auto exception = Tools::CheckParameterNumber(_parameterNumber);
    if (exception != nullptr) {
      throw exception;
    }

    long errorNumber = 0;
    int par = Get_Par(_parameterNumber, _adwinSystem->GetDeviceNumber(),
                      &errorNumber);

    if (errorNumber != 0) {
      throw ADwinSystemException(errorNumber);
    }
    return par;
  }

  void setValue(int value) {
    auto exception = Tools::CheckParameterNumber(_parameterNumber);
    if (exception != nullptr) {
      throw exception;
    }

    long errorNumber = 0;
    Set_Par(_parameterNumber, value, _adwinSystem->GetDeviceNumber(),
            &errorNumber);

    if (errorNumber != 0) {
      throw ADwinSystemException(errorNumber);
    }
  }

  ADwinSystem* _adwinSystem;
  int _parameterNumber;
};

Parameter::Parameter(ADwinSystem* adwinSystem, int parameterNumber)
    : _impl(new Impl(adwinSystem, parameterNumber)) {}

Parameter::~Parameter() = default;

int Parameter::value() const { return _impl->value(); }
void Parameter::setValue(int value) { _impl->setValue(value); }
}  // namespace Driver
}  // namespace ADwin